using System;
using System.Collections.Generic;
using System.Xml;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using System.Timers;

namespace Campus
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Campus : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        InputHandler inputHandler;

        // Audio declarations
        AudioEngine engine;
        SoundBank soundBank;
        WaveBank waveBank;

        // Font Declarations
        SpriteFont header, regular, small;

        // Menu Declarations
        //KeyboardMenu buildMenu;
        Texture2D backgroundTexture;
        //Texture2D selectTile;

        // New Menu Declarations
        MouseMenu menuMain;
        MouseMenu menuOptions;
        MouseMenu menuMainButton;

        MouseMenu credits;
        bool creditsUp = false;

        MouseMenu actionMouseMenu;

        // Cursor Declaration
        static public Cursor cursor;
        Rectangle scrollingArea;
        //Dictionary<String, Cursor> cursorList;
        //String cursorName;

        // Game music
        Cue bgMusic;
        // Temp music (for credits, now)
        Cue playCue;

        // Selection Box Declaration
        SelectionBox selectBox;

        //Hud Declarations
        HUD hud;
        int topHUDHeight = 48;
        int bottomHUDHeight = 160;

        // Player declarations.
        Player player;
        bool lose = false;
        bool win = false;
        bool levelStarted = false;

        // Level Declarations
        Level currentLevel;
        Dictionary<string, Texture2D> terrainTextures = new Dictionary<string, Texture2D>();
        Dictionary<Terrain, Tile> tiles = new Dictionary<Terrain, Tile>();
        float LEVELDRAWSCALE = 1.0f;
        Vector2 DISTANCEBETWEENORIGINS = new Vector2(32, 20);

        public Campus()
        {
            graphics = new GraphicsDeviceManager(this);

            graphics.PreferredBackBufferWidth = ResolutionHandler.WindowWidth;
            graphics.PreferredBackBufferHeight = ResolutionHandler.WindowHeight;

            Content.RootDirectory = "Content";
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // Initialize unit animations *temporary*
            MechanicalEngineer.InitializeAnimations(Content);
            Physicist.InitializeAnimations(Content);

            Biologist.InitializeAnimalAnimation(Content);
            Biologist.InitializeAnimations(Content);

            CampusShuttle.InitializeAnimations(Content);

            Robot.InitializeAnimations(Content);

            ComputerScientist.InitializeAnimations(Content);

            Architect.InitializeAnimations(Content);

            CollegeOfEngineering.InitializeTextures(Content);
            CleanRoom.InitializeTextures(Content);
            ExperimentalLaboratory.InitializeTextures(Content);
            Scholarship.InitializeTextures(Content);
            SchoolCafeteria.InitializeTextures(Content);
            MothersBasement.InitializeTextures(Content);
            Dispatch.InitializeTextures(Content);
            InterdimensionalPortal.InitializeTextures(Content);

            GatewayToHell.InitializeTextures(Content);
            DownByTheRiver.InitializeTextures(Content);
            CollegeOfArchitecture.InitializeTextures(Content);
            CoffeeShop.InitializeTextures(Content);

            MenuIcons.InitializeIcons(Content);

            // Initialize audio objects.
            engine = new AudioEngine("Content\\Audio\\CampusAudio.xgs");
            soundBank = new SoundBank(engine, "Content\\Audio\\CampusAudio.xsb");
            waveBank = new WaveBank(engine, "Content\\Audio\\CampusAudio.xwb");

            bgMusic = soundBank.GetCue("music_soft");
            bgMusic.Play();

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            inputHandler = new InputHandler();

            // Set up the main font.
            header = Content.Load<SpriteFont>("Fonts/ArialLarge");
            regular = Content.Load<SpriteFont>("Fonts/Arial");
            small = Content.Load<SpriteFont>("Fonts/ArialSmall");

            // Load the selection circle used by Level for selected units/buildings
            Level.UnitSelectionCircle = Content.Load<Texture2D>("Level/unitselector");
            Level.BuildingSelectionCircle = Content.Load<Texture2D>("Level/buildingselector");

            // Load the 'background image' used for avoiding the smearing effect
            backgroundTexture = Content.Load<Texture2D>("Misc/1px_white");

            // Load up the cursor
            LoadCursor();

            // Load up our key-bindings.
            LoadKeyBindings();

            // Load up the main menu.
            LoadMainMenu();

            // Load the options menu
            LoadOptionsMenu();

            // Load the terrain textures.
            LoadTerrainTiles();

            // Load up a level that can be displayed behind the menu.
            startBackgroundMap();

            // Load up the default HUD.
            LoadHud();

            // Now that everything's loaded, create the player.
            player = new Player(Content, PlayerRace.Sciences, hud);

            // Load up the selection box
            LoadSelectionBox();

            // Load the menu button menu (invisible with only one button)
            LoadMenuButtonMenu();

            //Load the HUD action buttons menu
            LoadActionMenuTest();

            // Load the credits menu
            LoadCreditsMenu();
        }

        private void LoadMenuButtonMenu()
        {
            Dictionary<MenuButtonState, Texture2D> buttonTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("MenuButton/menuButtonNormal") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("MenuButton/menuButtonMouseover") },
                { MenuButtonState.active, Content.Load<Texture2D>("MenuButton/menuButtonPressed") }
            };

            MenuButton menuButton = new MenuButton(buttonTextures,
                                                   Vector2.Zero,
                                                   "mainmenu",
                                                   (x) => { menuMain.ToggleVisibility(); });

            menuMainButton = new MouseMenu(null, new Vector2(5, 5), new List<MenuButton>() { menuButton }, null);

            menuMainButton.Visible = true;
        }

        private void LoadActionMenuTest()
        {

            //int minWidth = 800;
            int realWidth = ResolutionHandler.WindowWidth;

            //int minHeight = 300;
            int realHeight = ResolutionHandler.WindowHeight;


            Dictionary<MenuButtonState, Texture2D> buttonTextures1 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_idle_with_icon_01_attack") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_mouseover_with_icon_01_attack") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_pressed_with_icon_01_attack") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures2 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_idle_with_icon_02_stop") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_mouseover_with_icon_02_stop") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_pressed_with_icon_02_stop") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures3 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_idle_with_icon_03_move") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_mouseover_with_icon_03_move") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_pressed_with_icon_03_move") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures4 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_04") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_04") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_04") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures5 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_05") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_05") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_05") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures6 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_06") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_06") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_06") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures7 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_with_icon_07_build") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_with_icon_07_build") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_with_icon_07_build") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures8 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_08") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_08") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_08") }
            };
            Dictionary<MenuButtonState, Texture2D> buttonTextures9 = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_09") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_09") },
                { MenuButtonState.active, Content.Load<Texture2D>("HUD/bottombar/actionbutton/action_button_gray_09") }
            };

            MenuButton button1 = new MenuButton(buttonTextures1,
                                                   Vector2.Zero,
                                                   "actionbutton1",
                                                   (x) => { cursor.ActionState = CursorActionState.move; });

            MenuButton button2 = new MenuButton(buttonTextures2,
                                                   new Vector2(49, 0),
                                                   "actionbutton2",
                                                   (x) => { 
                                                       foreach(BaseEntity baseEntity in player.Selected) {
                                                           baseEntity.Stop();
                                                       }
                                                   });
            MenuButton button3 = new MenuButton(buttonTextures3,
                                                   new Vector2(98, 0),
                                                   "actionbutton3",
                                                   (x) => { cursor.ActionState = CursorActionState.attack; });

            MenuButton button4 = new MenuButton(buttonTextures4,
                                                   new Vector2(0, 49),
                                                   "actionbutton4",
                                                   (x) => { });
            MenuButton button5 = new MenuButton(buttonTextures5,
                                                   new Vector2(49, 49),
                                                   "actionbutton5",
                                                   (x) => { });
            MenuButton button6 = new MenuButton(buttonTextures6,
                                                   new Vector2(98, 49),
                                                   "actionbutton6",
                                                   (x) => { });
            MenuButton button7 = new MenuButton(buttonTextures7,
                                                   new Vector2(0, 98),
                                                   "actionbutton7",
                                                   (x) => { });
            MenuButton button8 = new MenuButton(buttonTextures8,
                                                   new Vector2(49, 98),
                                                   "actionbutton8",
                                                   (x) => { });
            MenuButton button9 = new MenuButton(buttonTextures9,
                                                   new Vector2(98, 98),
                                                   "actionbutton9",
                                                   (x) => { });

            actionMouseMenu = new MouseMenu(null, new Vector2(realWidth - 152, realHeight - 152), new List<MenuButton>() { button1, button2, button3, 
                                                                                                 button4, button5, button6, 
                                                                                                 button7, button8, button9 }, null);

            actionMouseMenu.Visible = true;
        }

        private Dictionary<MenuButtonState, Texture2D> GetBlankButtonTextures(int buttonNum) {
            Dictionary<MenuButtonState, Texture2D> buttonTextures = new Dictionary<MenuButtonState, Texture2D>();
            string buttonTextureFile = "HUD/bottombar/actionbutton/action_button_gray_0" + buttonNum.ToString();
            buttonTextures.Add(MenuButtonState.idle, Content.Load<Texture2D>(buttonTextureFile));
            buttonTextures.Add(MenuButtonState.active, Content.Load<Texture2D>(buttonTextureFile));
            buttonTextures.Add(MenuButtonState.rollover, Content.Load<Texture2D>(buttonTextureFile));
            
            return buttonTextures;
        }

        private void LoadActionMouseMenu(BaseEntity be) {

            int realWidth = ResolutionHandler.WindowWidth;

            int realHeight = ResolutionHandler.WindowHeight;
            List<MenuButton> buttons = new List<MenuButton>();
            for(int i = 0; i < 9; i++) {
                buttons.Add(null);
            }
            
            if (be is Unit) {
                buttons[0] = new MenuButton(MenuIcons.MoveIcon.CreateMenuButtonTextures(),
                                                   Vector2.Zero,
                                                   "actionbutton1",
                                                   ((Unit)be).GetMoveAbility().Clone().MenuDelegate);

                buttons[1] = new MenuButton(MenuIcons.StopIcon.CreateMenuButtonTextures(),
                                                   new Vector2(49, 0),
                                                   "actionbutton2",
                                                   (x) => {
                                                       foreach (BaseEntity baseEntity in player.Selected) {
                                                           baseEntity.Stop();
                                                       }
                                                   });
            }
            if (be.Abilities.ContainsKey("Garrison") && !(be is BuildingStructure)) {
                buttons[6] = new MenuButton(MenuIcons.GarrisonIcon.CreateMenuButtonTextures(),
                                                   new Vector2(0, 98),
                                                   "actionbutton7",
                                                    be.Abilities["Garrison"].Clone().MenuDelegate);
            } else if (be is Structure) {
                buttons[6] = new MenuButton(GetBlankButtonTextures(7),
                                                   new Vector2(0, 98),
                                                   "actionbutton7",
                                                   (x) => { });
            }
            if (be.Abilities.ContainsKey("Expell Units") && !(be is BuildingStructure)) {
                buttons[7] = new MenuButton(MenuIcons.ExpellIcon.CreateMenuButtonTextures(),
                                                   new Vector2(49, 98),
                                                   "actionbutton8",
                                                    be.Abilities["Expell Units"].Clone().MenuDelegate);
            } else if (be is Structure) {
                buttons[7] = new MenuButton(GetBlankButtonTextures(8),
                                                   new Vector2(49, 98),
                                                   "actionbutton8",
                                                   (x) => { });
            }
            if (be.CanAttack) {
                buttons[2] = new MenuButton(be.GetAttackAbility().MenuIcon.CreateMenuButtonTextures(),
                                                   new Vector2(98, 0),
                                                   "actionbutton3",
                                                   be.GetAttackAbility().Clone().MenuDelegate);
            } else {
                buttons[2] = new MenuButton(GetBlankButtonTextures(3),
                                                   new Vector2(98, 0),
                                                   "actionbutton3",
                                                   (x) => { });
            }

            Dictionary<string, Ability>.Enumerator abilityEnumerator = be.Abilities.GetEnumerator();
            bool endAbilities = !abilityEnumerator.MoveNext();
            for (int i = 0; i < 9; i++ ) {
                if (buttons[i] == null) {
                    while (abilityEnumerator.Current.Key == "Attack" ||
                        abilityEnumerator.Current.Key == "Garrison" ||
                        abilityEnumerator.Current.Key == "Expell Units" ||
                        abilityEnumerator.Current.Key == "Move") {
                        if (!abilityEnumerator.MoveNext()) {
                            endAbilities = true;
                            break;
                        }
                    }
                    if (!endAbilities) {
                        buttons[i] = new MenuButton(abilityEnumerator.Current.Value.MenuIcon.CreateMenuButtonTextures(),
                                                   new Vector2((i % 3) * 49, ((int)(i / 3)) * 49),
                                                   "actionbutton" + (i + 1),
                                                   abilityEnumerator.Current.Value.Clone().MenuDelegate);
                        endAbilities = !abilityEnumerator.MoveNext();
                    } else {
                        buttons[i] = new MenuButton(GetBlankButtonTextures(i + 1),
                                                    new Vector2((i % 3) * 49, ((int)(i / 3)) * 49),
                                                    "actionbutton" + (i + 1),
                                                    (x) => { });
                    }
                }
            }
            actionMouseMenu = new MouseMenu(null, new Vector2(realWidth - 152, realHeight - 152), buttons, null);

            actionMouseMenu.Visible = true;
        }

        private void LoadCreditsMenu()
        {
            Dictionary<MenuButtonState, Texture2D> closeTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Misc/close_button_idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Misc/close_button_mouseover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Misc/close_button_pressed") }
            };

            MenuButton closeMenuButton = new MenuButton(closeTextures,
                                                        new Vector2(318, 89),
                                                        "close",
                                                        (x) => { credits.ToggleVisibility(); });

            List<MenuButton> buttonList = new List<MenuButton>() { closeMenuButton };

            // Animated graphic

            // ==== Loading the 'funk' animation ====
            List<Texture2D> frames = new List<Texture2D>();
            frames = new List<Texture2D>();

            for (int frame = 1; frame <= 44; frame++)
            {
                frames.Add(Content.Load<Texture2D>("Menu/Credits/funk/funk_" + ((frame <= 9) ? ("0" + frame.ToString()) : frame.ToString())));
                //clickFrames.Add(Content.Load<Texture2D>("Menu/Credits/funk/red_funk_" + ((frame <= 9) ? ("0" + frame.ToString()) : frame.ToString())));
            }

            AnimatedMenuGraphic amg = new AnimatedMenuGraphic(new Animation(frames, 95, true), new Vector2(156, 352));

            List<AnimatedMenuGraphic> amgList = new List<AnimatedMenuGraphic> { amg };

            credits = new MouseMenu(Content.Load<Texture2D>("Menu/Credits/credits"),
                                     new Vector2(200, 75),
                                     null,
                                     amgList,
                                     buttonList,
                                     Keys.C);
        }
        
        private void LoadOptionsMenu()
        {
            #region ----1024x768----

            Dictionary<MenuButtonState, Texture2D> textures1024 = new Dictionary<MenuButtonState, Texture2D>() 
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/1024x768idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/1024x768rollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/1024x768active") },
            };

            MenuButton button1024 = new MenuButton(textures1024, new Vector2(64, 124), "1024*768", (x) => 
                                                   {
                                                       menuOptions.SetButtonAsSelected("1024*768");
                                                       ResolutionHandler.ChangeResolution(x, 
                                                       this.currentLevel, graphics); 
                                                   });

            #endregion

            #region ----1280x800----

            Dictionary<MenuButtonState, Texture2D> textures1280 = new Dictionary<MenuButtonState, Texture2D>() 
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/1280x800idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/1280x800rollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/1280x800active") },
            };

            MenuButton button1280 = new MenuButton(textures1280, new Vector2(64, 183), "1280*800", (x) =>
                                                   {
                                                       menuOptions.SetButtonAsSelected("1280*800");
                                                       ResolutionHandler.ChangeResolution(x,
                                                       this.currentLevel, graphics);
                                                   });
            #endregion

            #region ----1920x1200----

            Dictionary<MenuButtonState, Texture2D> textures1920 = new Dictionary<MenuButtonState, Texture2D>() 
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/1920x1200idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/1920x1200rollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/1920x1200active") },
            };

            MenuButton button1920 = new MenuButton(textures1920, new Vector2(64, 242), "1920*1200", (x) =>
                                                   {
                                                       menuOptions.SetButtonAsSelected("1920*1200");
                                                       ResolutionHandler.ChangeResolution(x,
                                                       this.currentLevel, graphics);
                                                   });

            #endregion

            #region ----800x600----

            Dictionary<MenuButtonState, Texture2D> textures800 = new Dictionary<MenuButtonState, Texture2D>() 
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/800x600idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/800x600rollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/800x600active") },
            };

            MenuButton button800 = new MenuButton(textures800, new Vector2(64, 65), "800*600", (x) =>
                                                   {
                                                       menuOptions.SetButtonAsSelected("800*600");
                                                       ResolutionHandler.ChangeResolution(x,
                                                       this.currentLevel, graphics);
                                                   });

            button800.Selected = true;

            #endregion

            #region ----Native----

            Dictionary<MenuButtonState, Texture2D> texturesNative = new Dictionary<MenuButtonState, Texture2D>() 
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/nativeidle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/nativerollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/nativeactive") },
            };

            MenuButton buttonNative = new MenuButton(texturesNative, new Vector2(64, 301), "Native", (x) =>
                                                     {
                                                         menuOptions.SetButtonAsSelected("Native");
                                                         ResolutionHandler.ChangeResolution(x,
                                                         this.currentLevel, graphics);
                                                     });

            #endregion

            #region ----Close----

            Dictionary<MenuButtonState, Texture2D> closeTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Misc/close_button_idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Misc/close_button_mouseover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Misc/close_button_pressed") }
            };

            MenuButton closeMenuButton = new MenuButton(closeTextures, new Vector2(252, 45), "close", (x) => 
                                                        { 
                                                            menuOptions.ToggleVisibility(); 
                                                        });

            #endregion

            #region ----Full Screen----

            Dictionary<MenuButtonState, Texture2D> fullScreenTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Options/fullscreenidle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Options/fullscreenrollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Options/fullscreenactive") }
            };

            MenuButton fullScreenButton = new MenuButton(fullScreenTextures, new Vector2(38, 45), "full_screen", (x) =>
                                                         {
                                                             ResolutionHandler.ToggleFullscreen(graphics);
                                                         });

            #endregion

            #region ----Menu Creation----

            List<MenuButton> buttonList = new List<MenuButton>() 
            {
                button1024, button1280, button1920, button800, buttonNative, closeMenuButton, fullScreenButton
            };

            menuOptions = new MouseMenu(Content.Load<Texture2D>("Menu/Options/optionsmenu"),
                                        new Vector2(0.0f, 0.0f), buttonList,
                                        Keys.O);

            Vector2 menuPosition = new Vector2((((float)ResolutionHandler.WindowWidth + 64.0f) / 2.0f) - (menuOptions.Texture.Width / 2.0f),
                                               (((float)ResolutionHandler.WindowHeight - 40.0f) / 2.0f) - (menuOptions.Texture.Height / 2.0f));

            // This needs to be done because if the position is not on a pixel, the anti-aliasing done
            // by XNA makes the menu look blurry
            menuPosition.X = (int)menuPosition.X;
            menuPosition.Y = (int)menuPosition.Y;

            menuOptions.Position = menuPosition;

            menuOptions.SelectedColor = Color.Yellow;

            #endregion
        }

        private void LoadSelectionBox()
        {
            SelectionBox.InitializeSelectionBoxTexture(Content);

            selectBox = new SelectionBox(player, new Rectangle(0, topHUDHeight,
                                                               ResolutionHandler.WindowWidth, 
                                                               ResolutionHandler.WindowHeight - (topHUDHeight + bottomHUDHeight)),
                                                               Color.YellowGreen, 1);
        }

        private void LoadCursor()
        {
            #region ====ACTION ANIMATIONS====

            #region ----IDLE ANIMATION----

            List<Texture2D> idleTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/cursoridle")
            };

            Animation idleAnimation = new Animation(idleTextures, 1000, false);

            #endregion

            #region ----CLICK ANIMATION----

            List<Texture2D> clickTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/cursorclick")
            };

            Animation clickAnimation = new Animation(clickTextures, 1000, false);

            #endregion

            #region ----MOVE ANIMATION----

            List<Texture2D> moveTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/spinmove/spinmove0"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove1"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove2"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove3"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove4"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove5"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove6"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove7"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove8"),
                Content.Load<Texture2D>("Cursor/spinmove/spinmove9")
            };

            Animation moveAnimation = new Animation(moveTextures, 30, true);

            #endregion

            #region ----ATTACK ANIMATION----

            List<Texture2D> attackTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/spinattack/spinattack0"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack1"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack2"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack3"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack4"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack5"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack6"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack7"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack8"),
                Content.Load<Texture2D>("Cursor/spinattack/spinattack9")
            };

            Animation attackAnimation = new Animation(attackTextures, 30, true);

            #endregion

            #endregion

            #region ====SCROLL ANIMATIONS====

            #region ----Upper Left----

            List<Texture2D> scrollULTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUL0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUL1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUL2")
            };

            Animation scrollULAnimation = new Animation(scrollULTextures, 200, true);

            #endregion

            #region ----Up----

            List<Texture2D> scrollUTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollU0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollU1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollU2")
            };

            Animation scrollUAnimation = new Animation(scrollUTextures, 200, true);

            #endregion

            #region ----Upper Right----

            List<Texture2D> scrollURTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUR0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUR1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollUR2")
            };

            Animation scrollURAnimation = new Animation(scrollURTextures, 200, true);

            #endregion

            #region ----Left----

            List<Texture2D> scrollLTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollL0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollL1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollL2")
            };

            Animation scrollLAnimation = new Animation(scrollLTextures, 200, true);

            #endregion

            #region ----Right----

            List<Texture2D> scrollRTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollR0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollR1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollR2")
            };

            Animation scrollRAnimation = new Animation(scrollRTextures, 200, true);

            #endregion

            #region ----Down Left----

            List<Texture2D> scrollDLTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDL0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDL1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDL2")
            };

            Animation scrollDLAnimation = new Animation(scrollDLTextures, 200, true);

            #endregion

            #region ----Down----

            List<Texture2D> scrollDTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollD0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollD1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollD2")
            };

            Animation scrollDAnimation = new Animation(scrollDTextures, 200, true);

            #endregion

            #region ----Down Right----

            List<Texture2D> scrollDRTextures = new List<Texture2D>()
            {
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDR0"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDR1"),
                Content.Load<Texture2D>("Cursor/scroll/cursorscrollDR2")
            };

            Animation scrollDRAnimation = new Animation(scrollDRTextures, 200, true);

            #endregion

            #endregion

            #region ====CURSOR CREATION====

            // Map the action animations to each appropriate state
            Dictionary<CursorActionState, Animation> actionDict = new Dictionary<CursorActionState, Animation>()
            {
                { CursorActionState.attack, attackAnimation },
                { CursorActionState.click, clickAnimation },
                { CursorActionState.idle, idleAnimation },
                { CursorActionState.move, moveAnimation }
            };

            // Map the scroll animations to each appropriate state
            Dictionary<CursorScrollState, Animation> scrollDict = new Dictionary<CursorScrollState, Animation>()
            {
                { CursorScrollState.scrollUL, scrollULAnimation },
                { CursorScrollState.scrollU, scrollUAnimation },
                { CursorScrollState.scrollUR, scrollURAnimation },
                { CursorScrollState.scrollL, scrollLAnimation },
                { CursorScrollState.scrollR, scrollRAnimation },
                { CursorScrollState.scrollDL, scrollDLAnimation },
                { CursorScrollState.scrollD, scrollDAnimation },
                { CursorScrollState.scrollDR, scrollDRAnimation }
            };

            cursor = new Cursor(actionDict, scrollDict);

            #endregion

            #region ====ORIGIN TWEAKING====

            cursor.ScrollOrigins[CursorScrollState.scrollU] = new Vector2(29, 0);
            cursor.ScrollOrigins[CursorScrollState.scrollUR] = new Vector2(39, 0);
            cursor.ScrollOrigins[CursorScrollState.scrollR] = new Vector2(47, 0);
            cursor.ScrollOrigins[CursorScrollState.scrollDL] = new Vector2(0, 65);
            cursor.ScrollOrigins[CursorScrollState.scrollD] = new Vector2(29, 65);
            cursor.ScrollOrigins[CursorScrollState.scrollDR] = new Vector2(39, 65);

            cursor.ActionOrigins[CursorActionState.attack] = new Vector2(43, 21);

            cursor.ActionOrigins[CursorActionState.move] = new Vector2(43, 21);

            #endregion

            scrollingArea = new Rectangle(0, topHUDHeight,
                                          ResolutionHandler.WindowWidth,
                                          ResolutionHandler.WindowHeight - (topHUDHeight + bottomHUDHeight));
        }

        private void LoadKeyBindings()
        {
            // Level bindings.  These bindings are here because the Level's binds cannot be wrapped in some
            //      if statement to determine if they are valid (such as the menu and hud IsVisible
            //      properties), so we must do any bind checking through this main game class.
            //inputHandler.Bind(Keys.Right, moveLevel, 0);
            //inputHandler.Bind(Keys.Left, moveLevel, 0);
            //inputHandler.Bind(Keys.Down, moveLevel, 0);
            //inputHandler.Bind(Keys.Up, moveLevel, 0);
        }

        // These are essentially macros, to make tile declarations a simpler process.
        private Tile TileLoad(String asset, int originX, int originY, Terrain tileEnum, bool isWalkable, Color minimapColor)
        {
            return TileLoad(asset, originX, originY, tileEnum, Color.White, isWalkable, minimapColor);
        }
        private Tile TileLoad(String asset, int originX, int originY, Terrain tileEnum, Color tint, bool isWalkable, Color minimapColor)
        {
            Texture2D tempTexture = Content.Load<Texture2D>(asset);
            Tile tempTile = new Tile(tempTexture, new Vector2(tempTexture.Width, tempTexture.Height), new Vector2(originX, originY), tint, SpriteEffects.None, isWalkable, minimapColor);
            tiles.Add(tileEnum, tempTile);
            return tempTile;
        }

        private void LoadTerrainTiles()
        {
            // Create the tiles to be passed to the Level object.

            // Testing textures (kept as an example, for now)
            //Texture2D undefinedTexture = Content.Load<Texture2D>("Level/testUndefined");
            //Tile undefined = new Tile(undefinedTexture, new Vector2(undefinedTexture.Width, undefinedTexture.Height), new Vector2(0, 28), Color.Red, SpriteEffects.None);
            //Texture2D grassTexture = Content.Load<Texture2D>("Level/testGrass");
            //Tile grass = new Tile(grassTexture, new Vector2(grassTexture.Width, grassTexture.Height), new Vector2(0, 28), Color.White, SpriteEffects.None, 1.0f);
            //Texture2D treeTexture = Content.Load<Texture2D>("Level/testTree");
            //Tile tree = new Tile(treeTexture, new Vector2(treeTexture.Width, treeTexture.Height), new Vector2(8, 38), Color.White, SpriteEffects.None);

            //Tile grass01 = TileLoad("Level/grass_01", 0, 25, Terrain.Grass);
            Tile grass02 = TileLoad("Level/grass_02", 0, 25, Terrain.Grass, true, Color.Green);

            Tile tree03 = TileLoad("Level/tree_03", 72, 100, Terrain.Tree, false, Color.DarkGreen);

            Tile dirt01 = TileLoad("Level/dirt_01", 0, 20, Terrain.Dirt1, true, Color.Khaki);
            Tile dirt02 = TileLoad("Level/dirt_02", 0, 20, Terrain.Dirt2, true, Color.Khaki);
            Tile dirt03 = TileLoad("Level/dirt_03", 0, 20, Terrain.Dirt3, true, Color.Khaki);

            Tile rock01 = TileLoad("Level/rock_01", 4, 26, Terrain.Boulder, false, Color.Gray);

            Tile mg01g1 = TileLoad("Level/multigrass_01_g1", 5, 25, Terrain.MG1a, true, Color.LightGreen);
            Tile mg01g2 = TileLoad("Level/multigrass_01_g2", 5, 25, Terrain.MG1b, true, Color.LightGreen);
            Tile mg01g3 = TileLoad("Level/multigrass_01_g3", 5, 25, Terrain.MG1c, true, Color.LightGreen);
            Tile mg01g4 = TileLoad("Level/multigrass_01_g4", 5, 25, Terrain.MG1d, true, Color.LightGreen);
            Tile mg01g5 = TileLoad("Level/multigrass_01_g5", 5, 25, Terrain.MG1e, true, Color.LightGreen);

            Tile ocean01 = TileLoad("Level/ocean_01", 0, 19, Terrain.Water1, false, Color.Blue);
            Tile ocean02 = TileLoad("Level/ocean_02", 0, 19, Terrain.Water2, false, Color.Blue);
            Tile ocean03 = TileLoad("Level/ocean_03", 0, 19, Terrain.Water3, false, Color.Blue);

            Tile swamp01 = TileLoad("Level/swamp_01", 0, 19, Terrain.Swamp1, false, Color.DarkKhaki);
            Tile swamp02 = TileLoad("Level/swamp_02", 0, 19, Terrain.Swamp2, false, Color.DarkKhaki);
            Tile swamp03 = TileLoad("Level/swamp_03", 0, 19, Terrain.Swamp3, false, Color.DarkKhaki);

            //Tile black_s = TileLoad("Level/black_01s", 0, 19, Terrain.Undefined);

            Tile foursquarecolor = TileLoad("Level/foursquare_color", 0, 19, Terrain.Undefined, true, Color.HotPink);

            Tile pavement_01 = TileLoad("Level/pavement_01", 4, 25, Terrain.Pavement, true, Color.White);

            Tile weaveA = TileLoad("Level/weave_a", 0, 19, Terrain.WeaveA, true, Color.DarkBlue);
            Tile weaveB = TileLoad("Level/weave_b", 0, 19, Terrain.WeaveB, true, Color.DarkBlue);
            Tile weaveC = TileLoad("Level/weave_c", 0, 19, Terrain.WeaveC, true, Color.DarkBlue);
            Tile weaveD = TileLoad("Level/weave_d", 0, 19, Terrain.WeaveD, true, Color.DarkBlue);

            Tile number1 = TileLoad("Level/number1", 1, 19, Terrain.PlayerStart1, true, Color.Red);
            Tile number2 = TileLoad("Level/number2", 1, 19, Terrain.PlayerStart2, true, Color.Blue);
            Tile number3 = TileLoad("Level/number3", 1, 19, Terrain.PlayerStart3, true, Color.Teal);
            Tile number4 = TileLoad("Level/number4", 1, 19, Terrain.PlayerStart4, true, Color.Purple);

        }

        private void LoadMainMenu()
        {
            // Create the buttons
            Dictionary<MenuButtonState, Texture2D> newGameTextures = new Dictionary<MenuButtonState, Texture2D>()
            { 
                { MenuButtonState.idle, Content.Load<Texture2D> ("Menu/Main/newgameidle") },
                { MenuButtonState.rollover, Content.Load<Texture2D> ("Menu/Main/newgamerollover") },
                { MenuButtonState.active, Content.Load<Texture2D> ("Menu/Main/newgameactive") }
            };

            MenuButton newGame = new MenuButton(newGameTextures,
                                                new Vector2(64, 64),
                                                "newgame",
                                                startRandomMap);

            Dictionary<MenuButtonState, Texture2D> optionsTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D> ("Menu/Main/optionsidle") },
                { MenuButtonState.rollover, Content.Load<Texture2D> ("Menu/Main/optionsrollover") },
                { MenuButtonState.active, Content.Load<Texture2D> ("Menu/Main/optionsactive") }
            };

            MenuButton options = new MenuButton(optionsTextures,
                                                new Vector2(64, 120),
                                                "options",
                                                (x) => { menuOptions.ToggleVisibility(); });

            Dictionary<MenuButtonState, Texture2D> exitTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Menu/Main/exitidle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Menu/Main/exitrollover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Menu/Main/exitactive") }
            };
            
            MenuButton exit = new MenuButton(exitTextures,
                                             new Vector2(64, 300),
                                             "exit",
                                             Close);

            Dictionary<MenuButtonState, Texture2D> closeTextures = new Dictionary<MenuButtonState, Texture2D>()
            {
                { MenuButtonState.idle, Content.Load<Texture2D>("Misc/close_button_idle") },
                { MenuButtonState.rollover, Content.Load<Texture2D>("Misc/close_button_mouseover") },
                { MenuButtonState.active, Content.Load<Texture2D>("Misc/close_button_pressed") }
            };

            MenuButton closeMenuButton = new MenuButton(closeTextures,
                                                        new Vector2(252, 45),
                                                        "close",
                                                        (x) => { menuMain.ToggleVisibility(); });

            List<MenuButton> buttonList = new List<MenuButton> { newGame, exit, closeMenuButton, options };

            // Create the menu
            menuMain = new MouseMenu(Content.Load<Texture2D>("Menu/Main/mainmenu"), 
                                     Vector2.Zero,
                                     null,
                                     null,
                                     buttonList, 
                                     Keys.Escape);

            // Create the menu position
            Vector2 menuPosition = new Vector2((((float)ResolutionHandler.WindowWidth + 64.0f ) / 2.0f) - (menuMain.Texture.Width / 2.0f),
                                              (((float)ResolutionHandler.WindowHeight - 40.0f ) / 2.0f) - (menuMain.Texture.Height / 2.0f));

            // This needs to be done because if the position is not on a pixel, the anti-aliasing done
            // by XNA makes the menu look blurry
            menuPosition.X = (int)menuPosition.X;
            menuPosition.Y = (int)menuPosition.Y;

            menuMain.Position = menuPosition;

            // Make the menu visible initially
            menuMain.Visible = true;
        }

        private void Close(string option)
        {
            //buildMenu.IsVisible = false;

            if (option == "exit")
                this.Exit();
        }

        private void LoadHud()
        {

            int minWidth = ResolutionHandler.MinimumWidth;
            int realWidth = ResolutionHandler.WindowWidth;

            int sizeDiff = realWidth - minWidth;
            int perSpacing = sizeDiff / 4;
            int leftovers = sizeDiff - (perSpacing * 4);

            int minHeight = ResolutionHandler.MinimumHeight;
            int realHeight = ResolutionHandler.WindowHeight;

            // This is the topbar

            Texture2D leftEdgeImage;
            Texture2D rightEdgeImage;
            Texture2D backgroundImage;

            //Texture2D menuButtonImage;
            Texture2D pizzaImage;
            Texture2D titleImage;
            Texture2D moneyImage;
            Texture2D researchImage;

            Texture2D messagesImage;

            SpriteFont pescadero;
            pescadero = Content.Load<SpriteFont>("HUD/topbar/Pescadero");
            SpriteFont pescaderoSmall;
            pescaderoSmall = Content.Load<SpriteFont>("HUD/bottombar/PescaderoSmall");

            leftEdgeImage = Content.Load<Texture2D>("HUD/topbar/leftEdge");
            rightEdgeImage = Content.Load<Texture2D>("HUD/topbar/rightEdge");
            backgroundImage = Content.Load<Texture2D>("HUD/topbar/background");

            //menuButtonImage = Content.Load<Texture2D>("HUD/topbar/menuButton");
            pizzaImage = Content.Load<Texture2D>("HUD/topbar/pizza");
            titleImage = Content.Load<Texture2D>("HUD/topbar/title");
            moneyImage = Content.Load<Texture2D>("HUD/topbar/money");
            researchImage = Content.Load<Texture2D>("HUD/topbar/research");

            messagesImage = Content.Load<Texture2D>("HUD/topbar/messages");

            hud = new HUD();

            InformationOverlay hudLeftEdge = new InformationOverlay(new Vector2(0, 0), new Vector2(6, 51), leftEdgeImage, Color.White);
            InformationOverlay hudRightEdge = new InformationOverlay(new Vector2(realWidth - 6, 0), new Vector2(6, 51), rightEdgeImage, Color.White);
            InformationOverlay hudBackground = new InformationOverlay(new Vector2(6, 0), new Vector2(realWidth - 12, 51), backgroundImage, Color.White);

            //InformationOverlay hudMenuButton = new InformationOverlay(new Vector2(6, 6), new Vector2(56, 34), menuButtonImage, Color.White);
            InformationOverlay hudPizza = new InformationOverlay(new Vector2(73 + perSpacing, 0), new Vector2(159, 54), pizzaImage, Color.White);
            InformationOverlay hudTitle = new InformationOverlay(new Vector2(246 + perSpacing * 2, 5), new Vector2(215, 38), titleImage, Color.White);
            InformationOverlay hudMoney = new InformationOverlay(new Vector2(473 + perSpacing * 3, 0), new Vector2(154, 54), moneyImage, Color.White);
            InformationOverlay hudResearch = new InformationOverlay(new Vector2(638 + perSpacing * 4, 0), new Vector2(154, 54), researchImage, Color.White);

            InformationOverlay hudPizzaInfo = new InformationOverlay(new Vector2(135, 4), new Vector2(89, 24), pescadero, "foodInfo", "-1/-1");
            InformationOverlay hudMoneyInfo = new InformationOverlay(new Vector2(535, 4), new Vector2(80, 24), pescadero, "moneyInfo", "-1");
            InformationOverlay hudResearchInfo = new InformationOverlay(new Vector2(701, 4), new Vector2(80, 24), pescadero, "researchInfo", "-1");

            // Player messages box - set to default sizing, although sizing is done inside HUD.cs
            InformationOverlay hudPlayerMessages = new InformationOverlay(new Vector2(5, 56), new Vector2(250, 25), messagesImage, Color.White);
            InformationOverlay hudPlayerMessagesInfo = new InformationOverlay(new Vector2(10, 61), new Vector2(245, 95), pescaderoSmall, "playerMessagesInfo", "");

            hud.AddInformationOverlay("leftEdge", hudLeftEdge);
            hud.AddInformationOverlay("rightEdge", hudRightEdge);
            hud.AddInformationOverlay("background", hudBackground);

            //hud.AddInformationOverlay("menuButton", hudMenuButton);
            hud.AddInformationOverlay("pizza", hudPizza);
            hud.AddInformationOverlay("title", hudTitle);
            hud.AddInformationOverlay("money", hudMoney);
            hud.AddInformationOverlay("research", hudResearch);

            hud.AddInformationOverlay("pizzaInfo", hudPizzaInfo);
            hud.AddInformationOverlay("moneyInfo", hudMoneyInfo);
            hud.AddInformationOverlay("researchInfo", hudResearchInfo);

            hud.AddInformationOverlay("playerMessages", hudPlayerMessages);
            hud.AddInformationOverlay("playerMessagesInfo", hudPlayerMessagesInfo);

            // This is the bottombar

            Texture2D leftEdgeBottomImage;
            Texture2D rightEdgeBottomImage;
            Texture2D middleBottomImage;

            leftEdgeBottomImage = Content.Load<Texture2D>("HUD/bottombar/leftEdge");
            rightEdgeBottomImage = Content.Load<Texture2D>("HUD/bottombar/rightEdge");
            middleBottomImage = Content.Load<Texture2D>("HUD/bottombar/middle");

            InformationOverlay hudMiddleBottom = new InformationOverlay(new Vector2(235, realHeight - 126), new Vector2(realWidth - 425, 126), middleBottomImage, Color.White);
            InformationOverlay hudLeftEdgeBottom = new InformationOverlay(new Vector2(0, realHeight - 160), new Vector2(235, 160), leftEdgeBottomImage, Color.White);
            InformationOverlay hudRightEdgeBottom = new InformationOverlay(new Vector2(realWidth - 190, realHeight - 160), new Vector2(190, 160), rightEdgeBottomImage, Color.White);
            
            hud.AddInformationOverlay("leftEdgeBottom", hudLeftEdgeBottom);
            hud.AddInformationOverlay("rightEdgeBottom", hudRightEdgeBottom);
            hud.AddInformationOverlay("middleBottom", hudMiddleBottom);

            // This is the bottombar

            Texture2D selectionAreaLeftImage;
            Texture2D selectionAreaMidImage;
            Texture2D selectionAreaRightImage;

            selectionAreaLeftImage = Content.Load<Texture2D>("HUD/bottombar/selection_area/selection_area_left");
            selectionAreaMidImage = Content.Load<Texture2D>("HUD/bottombar/selection_area/selection_area_mid");
            selectionAreaRightImage = Content.Load<Texture2D>("HUD/bottombar/selection_area/selection_area_right");

            InformationOverlay selectionAreaLeft = new InformationOverlay(new Vector2(202, realHeight - 118), new Vector2(12, 110), selectionAreaLeftImage, Color.White);
            InformationOverlay selectionAreaMid = new InformationOverlay(new Vector2(214, realHeight - 118), new Vector2(realWidth - 383, 110), selectionAreaMidImage, Color.White);
            InformationOverlay selectionAreaRight = new InformationOverlay(new Vector2(realWidth - 173, realHeight - 118), new Vector2(12, 110), selectionAreaRightImage, Color.White);

            hud.AddInformationOverlay("selectionAreaLeft", selectionAreaLeft);
            hud.AddInformationOverlay("selectionAreaMid", selectionAreaMid);
            hud.AddInformationOverlay("selectionAreaRight", selectionAreaRight);

            InformationOverlay constructingImage = new InformationOverlay(new Vector2(202 + 55, realHeight - 118 + 44), new Vector2(200, 25), middleBottomImage, Color.Teal);
            InformationOverlay constructingInfo = new InformationOverlay(new Vector2(202 + 5, realHeight - 118), new Vector2(200, 54), pescadero, "constructingInfo", "Constructing...");
            InformationOverlay singleSelectionHealthBarImage = new InformationOverlay(new Vector2(202 + 5, realHeight - 118 + 5), new Vector2(45, 10), middleBottomImage, Color.Green);
            InformationOverlay structureBuildingBarImage = new InformationOverlay(new Vector2(202 + 5, realHeight - 118 + 70), new Vector2(45, 10), middleBottomImage, Color.Teal);
            InformationOverlay hudUnitImage = new InformationOverlay(new Vector2(202 + 5, realHeight - 118 + 20), new Vector2(45, 45), null, Color.White);
            InformationOverlay hudUnitInfo = new InformationOverlay(new Vector2(262, realHeight - 118 + 5), new Vector2(realWidth - 383, 110), pescaderoSmall, "unitInfo", "Not updating.");

            hud.AddInformationOverlay("constructingInfo", constructingInfo);
            hud.AddInformationOverlay("constructingImage", constructingImage);
            hud.AddInformationOverlay("singleSelectionHealthBarImage", singleSelectionHealthBarImage);
            hud.AddInformationOverlay("structureBuildingBarImage", structureBuildingBarImage);
            hud.AddInformationOverlay("unitImage", hudUnitImage);
            hud.AddInformationOverlay("unitInfo", hudUnitInfo);

            // Build collection of image InformationOverlays for when multiple units are selected.
            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    InformationOverlay multiSelectedUnitHealthBarImage = new InformationOverlay(new Vector2(202 + 50 * j + 5, realHeight - 118 + 5 + (50 * i)), new Vector2(45, 10), middleBottomImage, Color.Green);
                    hud.AddInformationOverlay("unitHealthBarImage" + i + "" + j, multiSelectedUnitHealthBarImage);
                    InformationOverlay multiSelectedUnitImage = new InformationOverlay(new Vector2(202 + 50 * j + 5, realHeight - 118 + 5 + (50 * i)), new Vector2(45, 45), null, Color.White);
                    hud.AddInformationOverlay("unitImage" + i + "" + j, multiSelectedUnitImage);
                }
            }

            // Build collection of image InformationOverylays for when selecting structures that contain garrisoned units.
            for (int i = 0; i < 8; i++)
            {
                InformationOverlay garrisonedUnitImage = new InformationOverlay(new Vector2(202 + 30 * i + 5, realHeight - 38), new Vector2(25, 25), null, Color.White);
                hud.AddInformationOverlay("garrisonedUnitImage" + i, garrisonedUnitImage);
            }
        }

        private void moveLevel(Keys key, KeyState state)
        {
            if (key == Keys.Right)
                player.ScreenPosition += new Vector2(currentLevel.TileSize, 0);
            if (key == Keys.Left)
                player.ScreenPosition += new Vector2(-currentLevel.TileSize, 0);
            if (key == Keys.Down)
                player.ScreenPosition += new Vector2(0, currentLevel.TileSize);
            if (key == Keys.Up)
                player.ScreenPosition += new Vector2(0, -currentLevel.TileSize);
        }

        private void startBackgroundMap()
        {
            // Construct a level from the Map1.xml file and make it the current level as the "background"
            Level bgLevel = new Level(this, tiles, Content.Load<String>("Level/Map1"), DISTANCEBETWEENORIGINS, LEVELDRAWSCALE);

            currentLevel = bgLevel;
        }

        // Options used as delegates in a menu now require a string argument.  This string argument that is
        //      passed through the delegate is the Key (string/title/name) of the option that was selected.
        //      This allows us to make more generalized (albeit messier) code for the build and other
        //      functions.  What is nice about this though, is that it should allow us to put these kinds of
        //      functions inside a given unit class and call it through them rather than in the main game code.
        //int count = 1;
        private void Build(string option)
        {
            Vector2 worldMousePosition = new Vector2(player.MousePosition.X + player.ScreenPosition.X, player.MousePosition.Y + player.ScreenPosition.Y);
            Vector2 placeToBuild;

            // If there's a grid position that corresponds to the mouse position.
            if (currentLevel.GetGridPositionForPoint(worldMousePosition, out placeToBuild))
            {
                switch (option)
                {
                    case "Nexus":
                        player.CurrentLevel.AddBaseEntityToTile(new CollegeOfEngineering(player, player.CurrentLevel),
                            (int)placeToBuild.Y, (int)placeToBuild.X);
                        break;
                }
            }

            /*
             * LEGACY CODE FROM OLD BUILD STUFF JUST IN CASE
             * 
            if (option == "Build a Dorm" && player.CurrentUnit.Name == "Engineer")
            {
                MechanicalEngineer temp = (MechanicalEngineer)player.CurrentUnit;
                Vector2 placeToBuild = new Vector2(((int)((player.MousePosition.X + player.ScreenPosition.X) / 40) * 40),
                    ((int)((player.MousePosition.Y + player.ScreenPosition.Y) / 40) * 40));
                temp.Destination = placeToBuild;
                temp.BuildDestination = placeToBuild;
                temp.BuildString = "Build a Dorm";
                temp.IsBuilding = true;
            }
             */
        }

        private void startRandomMap(string option)
        {
            lose = false;
            levelStarted = false;

            // New Level construction code.
            Level revisedLevel = new Level(this, tiles, Content.Load<String>("Level/Map4"), DISTANCEBETWEENORIGINS, LEVELDRAWSCALE);

            // Clear the Player's list of owned BaseEntity objects.
            player.ResetPlayer();
            // Add the player to the Level.
            revisedLevel.AddPlayer(player);
            player.AddMoney(4000);
            player.AddResearch(4000);

            // Add an enemy player to the Level.
            Player otherPlayer = new Player(Content, PlayerRace.Sciences, hud);
            revisedLevel.AddPlayer(otherPlayer);

            currentLevel = revisedLevel;

            menuMain.ToggleVisibility();
            levelStarted = true;
            hud.IsVisible = true;
        }

        private void ReloadGUIElements()
        {
            // Change the current level's viewable area
            this.currentLevel.SetViewableArea(0, 0, ResolutionHandler.WindowWidth, ResolutionHandler.WindowHeight);

            // Change the scroll speed
            cursor.ScrollSpeed = ResolutionHandler.WindowHeight / 2;

            // Set the new position of the main menu
            Vector2 newPosition;

            #region ========MAIN MENU========

            newPosition = new Vector2((((float)ResolutionHandler.WindowWidth + 64.0f) / 2.0f) - (menuMain.Texture.Width / 2.0f),
                                      (((float)ResolutionHandler.WindowHeight - 40.0f) / 2.0f) - (menuMain.Texture.Height / 2.0f));

            // This needs to be done because if the position is not on a pixel, the anti-aliasing done
            // by XNA makes the menu look blurry
            newPosition.X = (int)newPosition.X;
            newPosition.Y = (int)newPosition.Y;

            menuMain.Position = newPosition;

            #endregion

            #region ========OPTIONS MENU========

            newPosition = new Vector2((((float)ResolutionHandler.WindowWidth + 64.0f) / 2.0f) - (menuOptions.Texture.Width / 2.0f),
                                      (((float)ResolutionHandler.WindowHeight - 40.0f) / 2.0f) - (menuOptions.Texture.Height / 2.0f));

            // This needs to be done because if the position is not on a pixel, the anti-aliasing done
            // by XNA makes the menu look blurry
            newPosition.X = (int)newPosition.X;
            newPosition.Y = (int)newPosition.Y;

            menuOptions.Position = newPosition;

            #endregion

            #region ========BUILD MENU=========

            newPosition.X = ResolutionHandler.WindowWidth - 152;
            newPosition.Y = ResolutionHandler.WindowHeight - 152;

            actionMouseMenu.Position = newPosition;

            #endregion

            #region ========SELECTABLE AND SCROLLING AREAS=========
            // Create the area valid for using the select box
            selectBox.SelectableArea = new Rectangle(0, topHUDHeight,
                                                     ResolutionHandler.WindowWidth,
                                                     ResolutionHandler.WindowHeight - (topHUDHeight + bottomHUDHeight));

            if (graphics.IsFullScreen)
            {
                // If it is full screen, change the scrolling area as the very edges of the screen
                scrollingArea = new Rectangle(0, 0, ResolutionHandler.WindowWidth, ResolutionHandler.WindowHeight);

                Cursor.SCROLL_BUFFER_SIZE = 5;
                Cursor.SCROLL_DELAY = 0;

                cursor.ScrollOrigins[CursorScrollState.scrollU] = new Vector2(29, 0);
                cursor.ScrollOrigins[CursorScrollState.scrollUR] = new Vector2(78, 0);
                cursor.ScrollOrigins[CursorScrollState.scrollR] = new Vector2(94, 0);
                cursor.ScrollOrigins[CursorScrollState.scrollDL] = new Vector2(0, 82);
                cursor.ScrollOrigins[CursorScrollState.scrollD] = new Vector2(29, 93);
                cursor.ScrollOrigins[CursorScrollState.scrollDR] = new Vector2(78, 82);
            }
            else
            {
                // If it is in a window, set the scrollable area as the game board area
                scrollingArea = selectBox.SelectableArea;

                Cursor.SCROLL_BUFFER_SIZE = 75;
                Cursor.SCROLL_DELAY = 250;
            }

            // Change the scrolling limit for the new resolution
            Vector2 limits = currentLevel.GetLevelSizeInPixels();

            Cursor.SCROLL_LIMIT_XMAX = (int)(limits.X - ResolutionHandler.WindowWidth + 100);
            Cursor.SCROLL_LIMIT_YMAX = (int)(limits.Y - ResolutionHandler.WindowHeight + 200);

            #endregion

            #region =======HUD========

            // Update the HUD's position
            Vector2 newSize;

            InformationOverlay leftOverlay;
            InformationOverlay middleOverlay;
            InformationOverlay rightOverlay;

            #region --------TOP---------

            leftOverlay = hud.GetInformationOverlay("leftEdge");
            middleOverlay = hud.GetInformationOverlay("background");
            rightOverlay = hud.GetInformationOverlay("rightEdge");

            #region -------Left-------

            // Nothing needs to be done

            #endregion

            #region -------Right-------

            newPosition.X = ResolutionHandler.WindowWidth - rightOverlay.Size.X;
            newPosition.Y = 0.0f;

            rightOverlay.Location = newPosition;

            #endregion

            #region -------Middle-------

            newSize.X = ResolutionHandler.WindowWidth - rightOverlay.Size.X - leftOverlay.Size.X;
            newSize.Y = middleOverlay.Size.Y;

            middleOverlay.Size = newSize;

            #endregion

            #region -------Elements-------

            InformationOverlay overlayGraphic;
            InformationOverlay overlayInformation;

            int perSpacing = (ResolutionHandler.WindowWidth - ResolutionHandler.MinimumWidth) / 4;

            #region ===Pizza===

            // Uncommenting will spread out the HUD elements

            /*
            overlayGraphic = hud.GetInformationOverlay("pizza");
            overlayInformation = hud.GetInformationOverlay("pizzaInfo");

            newPosition.X = 73 + perSpacing;
            newPosition.Y = overlayGraphic.Location.Y;

            overlayGraphic.Location = newPosition;

            newPosition.X = overlayGraphic.Location.X + 62;
            newPosition.Y = overlayInformation.Location.Y;

            overlayInformation.Location = newPosition;
            */ 

            #endregion

            #region ===Title===

            overlayGraphic = hud.GetInformationOverlay("title");

            newPosition.X = 246 + (perSpacing * 2);
            newPosition.Y = overlayGraphic.Location.Y;

            overlayGraphic.Location = newPosition;

            #endregion

            #region ===Money===

            overlayGraphic = hud.GetInformationOverlay("money");
            overlayInformation = hud.GetInformationOverlay("moneyInfo");

            newPosition.X = ResolutionHandler.WindowWidth - 327;
            // Uncommenting will spread out the HUD elements
            //newPosition.X = 473 + (perSpacing * 3);
            newPosition.Y = overlayGraphic.Location.Y;

            overlayGraphic.Location = newPosition;

            newPosition.X = newPosition.X = overlayGraphic.Location.X + 62;
            newPosition.Y = overlayInformation.Location.Y;

            overlayInformation.Location = newPosition;

            #endregion

            #region ===Research===

            overlayGraphic = hud.GetInformationOverlay("research");
            overlayInformation = hud.GetInformationOverlay("researchInfo");

            newPosition.X = ResolutionHandler.WindowWidth - 162;
            newPosition.Y = overlayGraphic.Location.Y;

            overlayGraphic.Location = newPosition;

            newPosition.X = newPosition.X = overlayGraphic.Location.X + 62;
            newPosition.Y = overlayInformation.Location.Y;

            overlayInformation.Location = newPosition;

            #endregion

            #endregion

            #endregion

            #region -------BOTTOM-------

            leftOverlay = hud.GetInformationOverlay("leftEdgeBottom");
            middleOverlay = hud.GetInformationOverlay("middleBottom");
            rightOverlay = hud.GetInformationOverlay("rightEdgeBottom");

            #region -------Left-------

            newPosition.X = 0.0f;
            newPosition.Y = ResolutionHandler.WindowHeight - leftOverlay.Size.Y;

            leftOverlay.Location = newPosition;

            if (player != null && player.Minimap != null)
            {
                // Change the location of the minimap
                newPosition.X += 11;
                newPosition.Y += 10;

                player.Minimap.StartPosition = newPosition;

                // You need to regenerate the terrain map since each terrain piece's location is hardwired
                player.Minimap.BuildTerrainMinimapUsingSprites();

                // Call the minimap's Update function to prevent the unit dots staying in their old location
                // until the menus disappear (the game is unpaused)
                player.Minimap.Update();
            }

            #endregion

            #region -------Right-------

            newPosition.X = ResolutionHandler.WindowWidth - rightOverlay.Size.X;
            newPosition.Y = ResolutionHandler.WindowHeight - rightOverlay.Size.Y;

            rightOverlay.Location = newPosition;

            #endregion

            #region -------Middle-------
            
            newPosition.X = leftOverlay.Size.X;
            newPosition.Y = ResolutionHandler.WindowHeight - middleOverlay.Size.Y;

            middleOverlay.Location = newPosition;
            
            // Stretch/shrink so it fits the entire empty space between the left and right overlays
            newSize = new Vector2(ResolutionHandler.WindowWidth - leftOverlay.Size.X - rightOverlay.Size.X, 
                                  middleOverlay.Size.Y);

            middleOverlay.Size = newSize;

            // Relocate/Resize the selected units box
            InformationOverlay selectBoxLeft = hud.GetInformationOverlay("selectionAreaLeft");
            newPosition.X = selectBoxLeft.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - (selectBoxLeft.Size.Y + 8);
            selectBoxLeft.Location = newPosition;

            InformationOverlay selectBoxMid = hud.GetInformationOverlay("selectionAreaMid");
            newPosition.X = selectBoxMid.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - (selectBoxMid.Size.Y + 8);
            selectBoxMid.Location = newPosition;

            newSize = new Vector2(ResolutionHandler.WindowWidth - 383, 110);
            selectBoxMid.Size = newSize;

            InformationOverlay selectBoxRight = hud.GetInformationOverlay("selectionAreaRight");
            newPosition.X = ResolutionHandler.WindowWidth - 173;
            newPosition.Y = ResolutionHandler.WindowHeight - (selectBoxRight.Size.Y + 8);
            selectBoxRight.Location = newPosition;

            // Do the selected units menu
            InformationOverlay unitImage = hud.GetInformationOverlay("unitImage");
            newPosition.X = unitImage.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118 + 20;
            unitImage.Location = newPosition;

            InformationOverlay unitInfo = hud.GetInformationOverlay("unitInfo");
            newPosition.X = unitInfo.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118 + 5;
            unitInfo.Location = newPosition;
            unitInfo.Size = new Vector2(ResolutionHandler.WindowWidth - 383, unitInfo.Size.Y);

            InformationOverlay singleSelectionHealthBar = hud.GetInformationOverlay("singleSelectionHealthBarImage");
            newPosition.X = singleSelectionHealthBar.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118 + 5;
            singleSelectionHealthBar.Location = newPosition;

            InformationOverlay structureBuildingBarImage = hud.GetInformationOverlay("structureBuildingBarImage");
            newPosition.X = structureBuildingBarImage.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118 + 70;
            structureBuildingBarImage.Location = newPosition;

            InformationOverlay constructingImage = hud.GetInformationOverlay("constructingImage");
            newPosition.X = constructingImage.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118 + 44;
            constructingImage.Location = newPosition;

            InformationOverlay constructingInfo = hud.GetInformationOverlay("constructingInfo");
            newPosition.X = constructingInfo.Location.X;
            newPosition.Y = ResolutionHandler.WindowHeight - 118;
            constructingInfo.Location = newPosition;

            for (int i = 0; i < 2; i++)
            {
                for (int j = 0; j < 8; j++)
                {
                    InformationOverlay multiSelected = hud.GetInformationOverlay("unitImage" + i + "" + j);
                    newPosition.X = multiSelected.Location.X;
                    newPosition.Y = ResolutionHandler.WindowHeight - 118 + 5;
                    multiSelected.Location = newPosition;

                    InformationOverlay multiSelectedHealthBar = hud.GetInformationOverlay("unitHealthBarImage" + i + "" + j);
                    newPosition.X = multiSelectedHealthBar.Location.X;
                    newPosition.Y = ResolutionHandler.WindowHeight - 118 + 5;
                    multiSelectedHealthBar.Location = newPosition;
                }
            }

            for (int i = 0; i < 8; i++)
            {
                InformationOverlay garrisonedUnitImage = hud.GetInformationOverlay("garrisonedUnitImage" + i);
                newPosition.X = garrisonedUnitImage.Location.X;
                newPosition.Y = ResolutionHandler.WindowHeight - 38;
                garrisonedUnitImage.Location = newPosition;
            }

            #endregion

            #endregion

            #endregion

            // The GUI has been fixed, it no longer needs to be reloaded
            ResolutionHandler.GUINeedsReloading = false;
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        private bool IsPaused()
        {
            return menuOptions.Visible || menuMain.Visible;
        }


        private BaseEntity m_lastSelectedUnit;
        static public bool ReloadActionMenu = false;
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        /// 
        protected override void Update(GameTime gameTime)
        {
            MouseState state = Mouse.GetState();

            Vector2 testPosition;

            currentLevel.GetGridPositionForPoint(new Vector2(state.X + player.ScreenPosition.X, state.Y + player.ScreenPosition.Y), out testPosition);

            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // Recenter all GUI elements if they need to be
            if (ResolutionHandler.GUINeedsReloading)
            {
                ReloadGUIElements();
            }

            // Cursor and the main menu need to be updated outside of the !menuMain.Visible statement
            // otherwise, you can't interact with the menu and the 'cursor' doesn't follow the mouse
            cursor.Update(gameTime, player, currentLevel, scrollingArea, IsPaused());

            // Only allow main menu interaction if the options menu is not visible
            if (!menuOptions.Visible)
            {
                menuMain.Update(gameTime);
            }

            menuOptions.Update(gameTime);
            menuMainButton.Update(gameTime);

            credits.Update(gameTime);

            // This is a HACK for when credits are shown
            if (credits.Visible)
            {
                if (!creditsUp)
                {
                    creditsUp = true;
                    bgMusic.Pause();
                    playCue = soundBank.GetCue("give_up_the_funk");
                    playCue.Play();
                    //SetCursor("funk");
                }
            }
            else
            {
                if (creditsUp)
                {
                    creditsUp = false;
                    playCue.Stop(AudioStopOptions.Immediate);
                    bgMusic.Resume();
                    //SetCursor("finger");
                }
            }

            // Change the visibility of the action menu
            if (player.CurrentUnit is BaseEntity && player.CurrentUnit.TeamNumber == player.TeamNumber)
            {
                if (player.CurrentUnit != m_lastSelectedUnit || ReloadActionMenu) {
                    LoadActionMouseMenu(player.CurrentUnit);
                    m_lastSelectedUnit = player.CurrentUnit;
                    ReloadActionMenu = false;
                }
                //TODO: need to find a way to reload the action menu after a button has been clicked
                actionMouseMenu.Visible = true;
            }
            else
            {
                actionMouseMenu.Visible = false;
            }

            if (!IsPaused())
            {
                inputHandler.CheckInputs();

                // Update the current level.
                currentLevel.Update(gameTime);

                selectBox.Update(currentLevel);

                actionMouseMenu.Update(gameTime);

                // this check should be unnecessary.  Building something should be an ability, so we just give
                //      the engineer an ability list that contains the buildings and then when you hit "b" it
                //      should open the ability list regardless of type of unit and show you what's in your
                //      ability list.
                //if (player.CurrentUnit != null && player.CurrentUnit.Name.Equals("Engineer"))
                //{
                //   buildMenu.m_isVisible = true;
                //}

                //buildMenu.Update();

                //abilityUpdate();

                //Update the Player (subsumed the hud update)
                player.Update(gameTime);

                foreach (Player currentPlayer in currentLevel.Players)
                {
                    for (int i = 0; i < currentPlayer.Added.Count; i++)
                    {
                        currentLevel.AddBaseEntity(currentPlayer.Added[i]);
                    }
                    currentPlayer.Added.Clear();

                    for (int i = 0; i < currentPlayer.Destroyed.Count; i++)
                    {
                        currentLevel.RemoveBaseEntity(currentPlayer.Destroyed[i]);
                        var destroyedUnit = currentPlayer.Destroyed[i] as Unit;

                        if (destroyedUnit != null && currentPlayer.Units.Contains(destroyedUnit))
                        {
                            currentPlayer.Units.Remove(destroyedUnit);
                        }
                        currentPlayer.Destroyed[i] = null;
                    }
                    currentPlayer.Destroyed.Clear();
                }
            }

            base.Update(gameTime);
        }
        /*
        private void abilityUpdate()
        {
            if (player.CurrentUnit != null && player.CurrentUnit.Name != "Engineer")
            {
                buildMenu.RemoveOption("Build a Dorm");
                buildMenu.RemoveOption("Build a Library");
                buildMenu.RemoveOption("Build Final Project");
            }
            else
            {
                if (!buildMenu.ContainsOption("Build a Dorm"))
                {
                    buildMenu.AddOption("Build a Dorm", Build);
                    buildMenu.AddOption("Build a Library", Build);
                    buildMenu.AddOption("Build Final Project", Build);
                }
            }
            if (player.CurrentUnit != null && player.CurrentUnit.Name != "Nexus")
            {
                buildMenu.RemoveOption("Build an Engineer");
                buildMenu.RemoveOption("Build a Physicist");
            }
            else
            {
                if (!buildMenu.ContainsOption("Build an Engineer"))
                {
                    buildMenu.AddOption("Build an Engineer", Build);
                    buildMenu.AddOption("Build a Physicist", Build);
                }
            }
            if (player.CurrentUnit == null)
            {
                buildMenu.RemoveOption("Build a Dorm");
                buildMenu.RemoveOption("Build a Library");
                buildMenu.RemoveOption("Build an Engineer");
                buildMenu.RemoveOption("Build a Physicist");
                buildMenu.RemoveOption("Build Final Project");
            }
        }
        */
        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            // Clear to the z-depth of .9.  Currently, everything above that (further away) is reserved for
            //      terrain so we can avoid drawing it repeatedly.
            graphics.GraphicsDevice.Clear(ClearOptions.DepthBuffer, Color.White, 0.9f, 0);

            // Draw a 'black background' to avoid the smearing effect
            spriteBatch.Begin();

            spriteBatch.Draw(backgroundTexture, 
                             new Rectangle(0, 0, ResolutionHandler.WindowWidth, ResolutionHandler.WindowHeight),    
                             Color.Black);

            spriteBatch.End();
            
            // Draw the current level with all the entities
            currentLevel.Draw(spriteBatch, graphics, player);
            
            // Draw the main menu.
            menuMain.Draw(spriteBatch);

            // Draw the credits menu
            credits.Draw(spriteBatch);

            // Draw the options menu
            menuOptions.Draw(spriteBatch);

            selectBox.Draw(spriteBatch);

            //Draw the HUD and minimap.
            player.Draw(spriteBatch);

            // Draw the menu button only if the game is started
            if (levelStarted)
            {
                menuMainButton.Draw(spriteBatch);
            }

            actionMouseMenu.Draw(spriteBatch);

            cursor.Draw(spriteBatch);
            
            base.Draw(gameTime);
           
        }
    }
}
